package com.yuanqi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanqi.pojo.CommodityCategory;
import com.yuanqi.pojo.Product;
import com.yuanqi.service.CommodityCategoryService;
import com.yuanqi.service.ProductService;
import com.yuanqi.mapper.CommodityCategoryMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author LENOVO
* @description 针对表【commodity_category(商品类目)】的数据库操作Service实现
* @createDate 2025-08-26 15:23:58
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class CommodityCategoryServiceImpl extends ServiceImpl<CommodityCategoryMapper, CommodityCategory>
    implements CommodityCategoryService{

    private final ProductService productService;

    @Override
    public List<CommodityCategory> listTree() {
        // 1. 查询所有启用的分类（可根据需求调整条件，如包含停用分类）
        LambdaQueryWrapper<CommodityCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommodityCategory::getStatus, 1); // 只查启用的分类
        List<CommodityCategory> allCategories = list(wrapper);

        // 2. 按 parentId 分组，注意：groupingBy 不接受 null key，这里将 null 映射为 -1L
        Map<Long, List<CommodityCategory>> parentMap = allCategories.stream()
                .collect(Collectors.groupingBy(c -> c.getParentId() == null ? -1L : c.getParentId()));

        // 3. 递归构建树形结构，从一级分类（parentId 为 null → 这里映射为 -1L）开始
        List<CommodityCategory> rootList = new ArrayList<>();
        List<CommodityCategory> roots = parentMap.getOrDefault(-1L, new ArrayList<>());
        for (CommodityCategory root : roots) {
            rootList.add(buildTree(root, parentMap));
        }
        return rootList;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCategoryWithProducts(Long categoryId) {
        try {
            log.info("开始级联删除分类及其商品，分类ID: {}", categoryId);
            
            // 1. 先删除该分类下的所有商品
            LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
            productWrapper.eq(Product::getCategoryId, categoryId);
            long productCount = productService.count(productWrapper);
            boolean productsDeleted = productService.remove(productWrapper);
            
            log.info("删除分类下的商品，分类ID: {}, 商品数量: {}, 删除结果: {}", 
                    categoryId, productCount, productsDeleted);
            
            // 2. 再删除分类本身
            boolean categoryDeleted = removeById(categoryId);
            
            log.info("删除分类，分类ID: {}, 删除结果: {}", categoryId, categoryDeleted);
            
            return productsDeleted && categoryDeleted;
        } catch (Exception e) {
            log.error("删除分类及其商品失败，分类ID: {}, 错误: {}", categoryId, e.getMessage(), e);
            throw new RuntimeException("删除分类失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCategoryRecursively(Long categoryId) {
        try {
            log.info("开始递归级联删除分类及其子分类下的所有商品，分类ID: {}", categoryId);
            
            // 1. 获取所有需要删除的分类ID（包括子分类）
            List<Long> allCategoryIds = getAllChildCategoryIds(categoryId);
            allCategoryIds.add(categoryId); // 添加当前分类ID
            
            log.info("需要删除的分类ID列表: {}", allCategoryIds);
            
            // 2. 删除这些分类下的所有商品
            LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
            productWrapper.in(Product::getCategoryId, allCategoryIds);
            long productCount = productService.count(productWrapper);
            boolean productsDeleted = productService.remove(productWrapper);
            
            log.info("删除分类及其子分类下的商品，分类ID: {}, 商品数量: {}, 删除结果: {}", 
                    categoryId, productCount, productsDeleted);
            
            // 3. 删除所有相关分类
            boolean categoriesDeleted = removeByIds(allCategoryIds);
            
            log.info("删除分类及其子分类，分类ID: {}, 删除结果: {}", categoryId, categoriesDeleted);
            
            return productsDeleted && categoriesDeleted;
        } catch (Exception e) {
            log.error("递归删除分类及其商品失败，分类ID: {}, 错误: {}", categoryId, e.getMessage(), e);
            throw new RuntimeException("递归删除分类失败: " + e.getMessage());
        }
    }
    
    @Override
    public long countProductsByCategory(Long categoryId) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getCategoryId, categoryId);
        return productService.count(wrapper);
    }
    
    @Override
    public long countProductsByCategoryRecursively(Long categoryId) {
        try {
            // 获取所有子分类ID
            List<Long> allCategoryIds = getAllChildCategoryIds(categoryId);
            allCategoryIds.add(categoryId); // 添加当前分类ID
            
            // 统计所有相关分类下的商品数量
            LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Product::getCategoryId, allCategoryIds);
            return productService.count(wrapper);
        } catch (Exception e) {
            log.error("统计分类及其子分类下的商品数量失败，分类ID: {}, 错误: {}", categoryId, e.getMessage(), e);
            return 0;
        }
    }
    
    /**
     * 递归获取所有子分类ID
     * @param parentId 父分类ID
     * @return 子分类ID列表
     */
    private List<Long> getAllChildCategoryIds(Long parentId) {
        List<Long> childIds = new ArrayList<>();
        
        // 查询直接子分类
        LambdaQueryWrapper<CommodityCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommodityCategory::getParentId, parentId);
        List<CommodityCategory> children = list(wrapper);
        
        for (CommodityCategory child : children) {
            childIds.add(child.getId());
            // 递归获取子分类的子分类
            childIds.addAll(getAllChildCategoryIds(child.getId()));
        }
        
        return childIds;
    }
    
    /**
     * 递归构建树形结构
     * @param node 当前分类节点
     * @param parentMap 按 parentId 分组的分类映射
     * @return 包含子分类的节点
     */
    private CommodityCategory buildTree(CommodityCategory node, Map<Long, List<CommodityCategory>> parentMap) {
        List<CommodityCategory> children = parentMap.getOrDefault(node.getId(), new ArrayList<>());
        for (CommodityCategory child : children) {
            buildTree(child, parentMap);
        }
        node.setChildren(children);
        return node;
    }

}




